# React plugin

import { SourceCode } from 'rspress/theme';

<SourceCode href="https://github.com/web-infra-dev/rsbuild/tree/main/packages/plugin-react" />

The React plugin provides support for React, integrating features such as JSX compilation and React Refresh.

## Quick start

### Install plugin

You can install the plugin using the following command:

import { PackageManagerTabs } from '@theme';

<PackageManagerTabs command="add @rsbuild/plugin-react -D" />

### Register plugin

You can register the plugin in the `rsbuild.config.ts` file:

```ts title="rsbuild.config.ts"
import { pluginReact } from '@rsbuild/plugin-react';

export default {
  plugins: [pluginReact()],
};
```

After registering the plugin, you can directly develop React.

## Options

### swcReactOptions

Configure the behavior of SWC to transform React code, the same as SWC's [jsc.transform.react](https://swc.rs/docs/configuration/compilation#jsctransformreact) option.

- **Type:**

```ts
interface ReactConfig {
  pragma?: string;
  pragmaFrag?: string;
  throwIfNamespace?: boolean;
  development?: boolean;
  refresh?:
    | boolean
    | {
        refreshReg?: string;
        refreshSig?: string;
        emitFullSignatures?: boolean;
      };
  runtime?: 'automatic' | 'classic';
  importSource?: string;
}
```

- **Default:**

```ts
const isDev = process.env.NODE_ENV === 'development';
const defaultOptions = {
  development: isDev,
  refresh: isDev,
  runtime: 'automatic',
};
```

### swcReactOptions.runtime

- **Type:** `'automatic' | 'classic'`
- **Default:** `'automatic'`

By default, Rsbuild uses the [new JSX runtime](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) introduced in React 17, which is `runtime: 'automatic'`.

If your current React version is lower than 16.14.0, you can set `runtime` to `'classic'`:

```ts
pluginReact({
  swcReactOptions: {
    runtime: 'classic',
  },
});
```

> React 16.14.0 can use the new JSX runtime.

When using the classic JSX runtime, you need to manually import React in your code:

```jsx
import React from 'react';

function App() {
  return <h1>Hello World</h1>;
}
```

### swcReactOptions.importSource

- **Type:** `string`
- **Default:** `'react'`

When `runtime` is `'automatic'`, you can specify the import path of the JSX runtime through `importSource`.

For example, when using [Emotion](https://emotion.sh/), you can set `importSource` to `'@emotion/react'`:

```ts
pluginReact({
  swcReactOptions: {
    importSource: '@emotion/react',
  },
});
```

> See [Customize JSX](/guide/framework/react#customize-jsx) for more details.

### swcReactOptions.refresh

- **Type:** `boolean`
- **Default:** based on [fastRefresh](#fastrefresh) and [dev.hmr](/config/dev/hmr)

Whether to enable [React Fast Refresh](https://npmjs.com/package/react-refresh).

Most of the time, you should use the plugin's [fastRefresh](#fastrefresh) option to enable or disable Fast Refresh.

### splitChunks

When [chunkSplit.strategy](/config/performance/chunk-split) set to `split-by-experience`, Rsbuild will automatically split `react` and `router` related packages into separate chunks by default:

- `lib-react.js`: includes react, react-dom, and react's sub-dependencies (scheduler).
- `lib-router.js`: includes react-router, react-router-dom, and react-router's sub-dependencies (history, @remix-run/router).

This option is used to control this behavior and determine whether the `react` and `router` related packages need to be split into separate chunks.

- **Type:**

```ts
type SplitReactChunkOptions = {
  react?: boolean;
  router?: boolean;
};
```

- **Default:**

```ts
const defaultOptions = {
  react: true,
  router: true,
};
```

- **Example:**

```ts
pluginReact({
  splitChunks: {
    react: false,
    router: false,
  },
});
```

### enableProfiler

- **Type:** `boolean`
- **Default:** `false`

When set to `true`, enables the React Profiler for performance analysis in production builds. Use the React DevTools to examine profiling results and identify potential performance optimizations. Profiling adds a slight overhead, so it's disabled by default in production mode.

```ts title="rsbuild.config.ts"
pluginReact({
  // Only enable the profiler when REACT_PROFILER is true,
  // as the option will increase the build time and adds some small additional overhead.
  enableProfiler: process.env.REACT_PROFILER === 'true',
});
```

Set `REACT_PROFILER=true` when running build script:

```json title="package.json"
{
  "scripts": {
    "build:profiler": "REACT_PROFILER=true rsbuild build"
  }
}
```

As Windows does not support the above usage, you can also use [cross-env](https://npmjs.com/package/cross-env) to set environment variables. This ensures compatibility across different systems:

```json title="package.json"
{
  "scripts": {
    "build:profiler": "cross-env REACT_PROFILER=true rsbuild build"
  },
  "devDependencies": {
    "cross-env": "^7.0.0"
  }
}
```

> See the [React docs](https://legacy.reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-devtools-profiler) for details about profiling using the React DevTools.

### reactRefreshOptions

- **Type:**

```ts
type ReactRefreshOptions = {
  include?: string | RegExp | (string | RegExp)[] | null;
  exclude?: string | RegExp | (string | RegExp)[] | null;
  library?: string;
  forceEnable?: boolean;
};
```

- **Default:**

```js
const defaultOptions = {
  include: [/\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/],
  exclude: [/[\\/]node_modules[\\/]/],
};
```

Set the options for [@rspack/plugin-react-refresh](https://github.com/rspack-contrib/rspack-plugin-react-refresh). The passed value will be shallowly merged with the default value.

- **Example:**

```js
pluginReact({
  reactRefreshOptions: {
    exclude: [/some-module-to-exclude/, /[\\/]node_modules[\\/]/],
  },
});
```

### fastRefresh

- **Type:** `boolean`
- **Default:** `true`

Whether to enable [React Fast Refresh](https://npmjs.com/package/react-refresh) in development mode.

If `fastRefresh` is set to `true`, `@rsbuild/plugin-react` will automatically register the [@rspack/plugin-react-refresh](https://github.com/rspack-contrib/rspack-plugin-react-refresh) plugin.

To disable Fast Refresh, set it to `false`:

```ts
pluginReact({
  fastRefresh: false,
});
```
